import 'dart:async';

import 'package:flustars/flustars.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import 'package:xiongmao_clean_flutter_module/util/toast_utils.dart';
import 'package:xiongmao_clean_flutter_module/widgets/xm_webview/xm_js_msg_call.dart';
import 'package:xiongmao_clean_flutter_module/widgets/xm_webview/xm_navigation_request.dart';
import 'package:xiongmao_clean_flutter_module/widgets/xm_webview/xm_web_res_error.dart';

import '../../net/http_config.dart';
import '../../res/colors.dart';
import '../../res/constant.dart';
import '../../util/common_utils.dart';
import '../../util/log_utils.dart';
import 'xm_web_controller.dart';

///
/// onXmJsMsgCall, onWebResourceError, onNavigationRequest 以及 controller 的逻辑
/// 均参考 webview_flutter 插件库的实现逻辑，后期如果需要替换 webview 插件的话，需对如上
/// 实现逻辑进行相应的改写
///
class XmWebView extends StatefulWidget {

  String? webUrl; // 默认加载链接
  String? jsName; // js 交互方法名称
  Color? bgColor; // 背景色
  Color? progressColor; // 加载进度条进度颜色
  void Function(String url)? onPageStarted; // 页面开始加载
  void Function(String url)? onPageFinished; // 页面加载完成
  void Function(int progress)? onProgress; // 加载进度
  void Function(XmJsMsgCall msgCall)? onXmJsMsgCall; // js 调用方法
  void Function(XmWebResError error)? onWebResourceError; // 资源加载错误设置
  Future<XmNavigationDecision> Function(XmNavigationRequest request)? onNavigationRequest; // 导航拦截/放行设置
  XmWebControllerSettingBack? controllerSettingBack; // controller 设置

  XmWebView({
    Key? key,
    this.webUrl,
    this.jsName,
    this.bgColor,
    this.progressColor,
    this.onXmJsMsgCall,
    this.onProgress,
    this.onPageStarted,
    this.onPageFinished,
    this.controllerSettingBack,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => _XmWebViewState();
}

class _XmWebViewState extends State<XmWebView> {
  final WebViewCookieManager cookieManager = WebViewCookieManager();
  late WebViewController selfController;
  late XmWebController xmWebController;
  double _progress = 0;
  bool _hadSetttingBack = false;

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (!_hadSetttingBack) {
        _hadSetttingBack = true;
        if (!TextUtil.isEmpty(widget.webUrl)) {
          selfController.loadRequest(Uri.parse(widget.webUrl!));
        }
        widget.controllerSettingBack?.call(xmWebController);
      }
    });

    late final PlatformWebViewControllerCreationParams params;
    if (WebViewPlatform.instance is WebKitWebViewPlatform) {
      params = WebKitWebViewControllerCreationParams(
        allowsInlineMediaPlayback: true,
        mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
      );
    } else {
      params = const PlatformWebViewControllerCreationParams();
    }

    selfController = WebViewController.fromPlatformCreationParams(params);
    xmWebController = XmWebController(selfController);
    // selfController.setUserAgent(CommonUtils.getMyUserAgent());
    selfController.setJavaScriptMode(JavaScriptMode.unrestricted); // 设置javascript 是能用的
    // selfController.addJavaScriptChannel(TextUtil.isEmpty(widget.jsName) ? Constant.jsSpaceName : widget.jsName!,
    selfController.addJavaScriptChannel(Constant.jsSpaceName,
      onMessageReceived: (message) {
      MyLog.e("msg---message---"+message.toString());
        widget.onXmJsMsgCall?.call(XmJsMsgCall(message));
      },
    );
    selfController
        .setBackgroundColor(widget.bgColor ?? const Color(0x00000000));

    _setCookies();

    selfController.setNavigationDelegate(
      NavigationDelegate(
        onProgress: (int progress) {
          widget.onProgress?.call(progress);
          if (!mounted) {
            return;
          }
          _progress = progress / 100;
          setState(() {});
        },
        onPageStarted: (String url) {
          widget.onPageStarted?.call(url);
          if (!mounted) {
            return;
          }
          _progress = 0;
          setState(() {});
        },
        onPageFinished: (String url) {
          widget.onPageFinished?.call(url);
          if (!mounted) {
            return;
          }
          _progress = 1;
          setState(() {});
        },
        onWebResourceError: (WebResourceError error) {

          XmWebResErrorType errType = XmWebResErrorType.unknown;
          if(error.errorType != null) {
            for (int i = 0; i < XmWebResErrorType.values.length; i++) {
              if(XmWebResErrorType.values[i].toString() == error.errorType.toString()) {
                errType = XmWebResErrorType.values[i];
                break;
              }
            }
          }
          widget.onWebResourceError?.call(XmWebResError(
              errorCode: error.errorCode,
              description: error.description,
              errorType: errType,
              isForMainFrame: error.isForMainFrame));
        },
        onNavigationRequest: (NavigationRequest request) async {
          if (widget.onNavigationRequest != null) {
            XmNavigationRequest xmRequest = XmNavigationRequest(url: request.url, isMainFrame: request.isMainFrame);
            XmNavigationDecision decision = await widget.onNavigationRequest!.call(xmRequest);
            if(decision == XmNavigationDecision.navigate) {
              return NavigationDecision.navigate; // 放行
            } else if(decision == XmNavigationDecision.prevent) {
              return NavigationDecision.prevent; // 拦截
            }
          }
          MyLog.e("msg---request.url----"+request.url);
          // todo... 暂时无需处理，不确定后续是否需要做特殊处理
          // //可以做以下功能 url 以 /android 结尾时，跳到对应的原生页面。否则继续原来的请求。
          // if (request.url.startsWith('http://www.employeasy.com/')) {
          //   CommonUtils.gotoBaseWebPage(request.url);
          //   return NavigationDecision.prevent;
          // }
          // 继续原来的请求
          return NavigationDecision.navigate;
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    WebViewWidget web = WebViewWidget(controller: selfController);
    return Stack(
      children: [
        web,
        Visibility(
            visible: _progress < 1,
            child: LinearProgressIndicator(
              minHeight: 1,
              backgroundColor: Colours.bg_color,
              valueColor: AlwaysStoppedAnimation(
                  widget.progressColor ?? Colours.base_primary),
              value: _progress,
            )),
      ],
    );
  }

  void _setCookies() async {
    // String token = SpUtil.getString(Constant.userToken) ?? "";
    // await cookieManager.setCookie(WebViewCookie(name: 'hmtoken', value: token, domain: _getWebDomain()));
    // await cookieManager.setCookie(WebViewCookie(
    //     name: 'hmlang',
    //     value: CommonUtils.getCurrentLocale(),
    //     domain: _getWebDomain()));
  }

  /// h5 页面 domain
  String _getWebDomain() {
    if (httpConfig.isReleaseServer()) {
      return "mh5.bluestarm.com";
    } else if (httpConfig.isDevServer()) {
      return "mh5-dev.bluestarm.com";
    } else {
      return "mh5-test.bluestarm.com";
    }
  }
}

typedef XmWebControllerSettingBack = void Function(XmWebController controller);
